﻿using System;
using System.Data.Common;
using System.Text;
using Sinacor.Infra.Service.Data;
using Sinacor.Process.Bovespa.Casamento.ProcessEntity;
using Sinacor.Infra.Service.Common;
using Sinacor.Infra.Service.Security.Authorization;
using System.Data;
using PSE.ProcessManager.Server.Process.Security;
using Sinacor.Infra.Core.ProcessManager.Server.Security;    

namespace Sinacor.Process.Bovespa.Casamento.Server.ResourceAccess
{
    /// <summary>
    /// Casamento
    /// </summary>
    public class Casamento:BaseResourceAccess
    {
        #region Construtores
        public Casamento() 
			: base(AuthenticationContext<SinacorAuthenticationData>.Current.AuthenticationData.CompanyId)
		{
		} 
		#endregion Construtores

        #region Métodos Públicos
        #region ExecutarCasamentoAutomatico
        /// <summary>
        /// ExecutarCasamentoAutomatico
        /// </summary>
        /// <param name="dataPregao">DateTime</param>
        /// <returns>ProcessEntity.Resultado</returns>
        public ProcessEntity.Resultado ExecutarCasamentoAutomatico(DateTime dataPregao)
        {
            return this.ExecutarCasamentoRecasamento(dataPregao, ProcessEntity.Enum.TipoExecucao.Casamento);
        }
        #endregion ExecutarCasamentoAutomatico
        #region ExecutarCasamentoAutomaticoPreBoleto
        /// <summary>
        /// ExecutarCasamentoAutomaticoPreBoleto
        /// </summary>
        /// <returns>ProcessEntity.Resultado</returns>
        public ProcessEntity.Resultado ExecutarCasamentoAutomaticoPreBoleto()
        {      
            StringBuilder _sql = new StringBuilder();
            ProcessEntity.Resultado _response = new ProcessEntity.Resultado();
            string _dataPregaoFormatada = string.Empty;

            using (DbCommand dbCommand = this.DataBase.GetSqlStringCommand(" "))
            {
                #region Query
                _sql.Append(@"
                         DECLARE rettype BOOLEAN;
                         BEGIN                      
                                rettype:= PR_CAAUTD.fOr_ExecutaCasamento(:R_nErro,:R_sErro,:R_sArgs);
                                IF rettype THEN :R_Retorno := 1; ELSE :R_Retorno := 0; END IF;
                         END; ");
                #endregion Query

                #region Parâmetros de Saída
                #region nErro
                DbParameter _parametroR_nErro = dbCommand.CreateParameter();

                _parametroR_nErro.ParameterName = "R_nErro";
                _parametroR_nErro.Direction = ParameterDirection.Output;
                _parametroR_nErro.DbType = DbType.Int32;
                _parametroR_nErro.Value = 0;

                dbCommand.Parameters.Add(_parametroR_nErro);
                #endregion nErro
                #region sErro
                DbParameter _parametroR_sErro = dbCommand.CreateParameter();

                _parametroR_sErro.ParameterName = "R_sErro";
                _parametroR_sErro.Direction = ParameterDirection.Output;
                _parametroR_sErro.DbType = DbType.String;
                _parametroR_sErro.Size = 4000;
                _parametroR_sErro.Value = null;

                dbCommand.Parameters.Add(_parametroR_sErro);
                #endregion sErro
                #region sArgs
                DbParameter _parametroR_sArgs = dbCommand.CreateParameter();

                _parametroR_sArgs.ParameterName = "R_sArgs";
                _parametroR_sArgs.Direction = ParameterDirection.Output;
                _parametroR_sArgs.DbType = DbType.String;
                _parametroR_sArgs.Size = 4000;
                _parametroR_sArgs.Value = null;

                dbCommand.Parameters.Add(_parametroR_sArgs);
                #endregion sArgs

                #region Retorno
                DbParameter _parametroRettype = dbCommand.CreateParameter();

                _parametroRettype.ParameterName = "R_Retorno";
                _parametroRettype.Direction = ParameterDirection.Output;
                _parametroRettype.DbType = DbType.Int32;
                _parametroRettype.Value = 0;

                dbCommand.Parameters.Add(_parametroRettype);
                #endregion Retorno
                #endregion Parâmetros de Saída

                #region Execute
                dbCommand.CommandText = _sql.ToString();
                this.DataBase.ExecuteNonQuery(dbCommand);

                _response.Sucesso = Convert.ToBoolean(this.DataBase.GetParameterValue(dbCommand, "R_Retorno")) ? true : false;

                if (!_response.Sucesso)
                {
                    _response.CodigoErro = Convert.ToInt32(_parametroR_nErro.Value);
                    _response.Argumentos = Convert.ToString(_parametroR_sArgs.Value);
                }
                #endregion Execute
            }
            return _response;
        }
        #endregion ExecutarCasamentoAutomaticoPreBoleto

        #region ExecutarRecasamentoAutomatico
        /// <summary>
        /// ExecutarRecasamentoAutomatico
        /// </summary>
        /// <param name="dataPregao">DateTime</param>
        /// <returns>ProcessEntity.Resultado</returns>
        public ProcessEntity.Resultado ExecutarRecasamentoAutomatico(DateTime dataPregao)
        {
            return ExecutarCasamentoRecasamento(dataPregao, ProcessEntity.Enum.TipoExecucao.Recasamento);
        }
        #endregion ExecutarRecasamentoAutomatico

        #endregion Métodos Públicos

        #region Métodos Privados    
        #region ExecutarCasamentoRecasamento
        /// <summary>
        /// ExecutarCasamentoRecasamento
        /// </summary>
        /// <param name="dataPregao">DateTime</param>
        /// <param name="execucao">ProcessEntity.Enum.TipoExecucao</param>
        /// <returns>ProcessEntity.Resultado</returns>
        private ProcessEntity.Resultado ExecutarCasamentoRecasamento(DateTime dataPregao, ProcessEntity.Enum.TipoExecucao execucao)
        {
            StringBuilder _sql = new StringBuilder();
            ProcessEntity.Resultado _response = new ProcessEntity.Resultado();
            string _dataPregaoFormatada = string.Empty;

            using (DbCommand dbCommand = this.DataBase.GetSqlStringCommand(" "))
            {
                #region Query
                _sql.Append(@"
                         DECLARE rettype BOOLEAN;
                         BEGIN 
                                rettype:= PR_CASAUT.fOr_CasaAut(:P_sDtPregao,:P_sTipoCasa,:R_nErro,:R_sErro,:R_sArgs);
                                IF rettype THEN :R_Retorno := 1; ELSE :R_Retorno := 0; END IF;
                         END; ");
                #endregion Query

                #region Parâmetros de Entrada
                #region Data Pregão
                _dataPregaoFormatada = this.FormatarData(dataPregao, "-");

                DbParameter _parametroP_sDtPregao = dbCommand.CreateParameter();

                _parametroP_sDtPregao.ParameterName = "P_sDtPregao";
                _parametroP_sDtPregao.Direction = ParameterDirection.Input;
                _parametroP_sDtPregao.DbType = DbType.AnsiString;
                _parametroP_sDtPregao.Value = _dataPregaoFormatada;

                dbCommand.Parameters.Add(_parametroP_sDtPregao);
                #endregion Data Pregão
                #region Execução
                DbParameter _parametroP_sTipoCasa = dbCommand.CreateParameter();

                _parametroP_sTipoCasa.ParameterName = "P_sTipoCasa";
                _parametroP_sTipoCasa.Direction = ParameterDirection.Input;
                _parametroP_sTipoCasa.DbType = DbType.String;
                _parametroP_sTipoCasa.Value = EnumConverter.ToString<ProcessEntity.Enum.TipoExecucao>(execucao);

                dbCommand.Parameters.Add(_parametroP_sTipoCasa);
                #endregion Execução
                #endregion Parâmetros de Entrada

                #region Parâmetros de Saída
                #region nErro
                DbParameter _parametroR_nErro = dbCommand.CreateParameter();

                _parametroR_nErro.ParameterName = "R_nErro";
                _parametroR_nErro.Direction = ParameterDirection.Output;
                _parametroR_nErro.DbType = DbType.Int32;
                _parametroR_nErro.Value = 0;

                dbCommand.Parameters.Add(_parametroR_nErro);
                #endregion nErro
                #region sErro
                DbParameter _parametroR_sErro = dbCommand.CreateParameter();

                _parametroR_sErro.ParameterName = "R_sErro";
                _parametroR_sErro.Direction = ParameterDirection.Output;
                _parametroR_sErro.DbType = DbType.String;
                _parametroR_sErro.Size = 4000;
                _parametroR_sErro.Value = null;

                dbCommand.Parameters.Add(_parametroR_sErro);
                #endregion sErro
                #region sArgs
                DbParameter _parametroR_sArgs = dbCommand.CreateParameter();

                _parametroR_sArgs.ParameterName = "R_sArgs";
                _parametroR_sArgs.Direction = ParameterDirection.Output;
                _parametroR_sArgs.DbType = DbType.String;
                _parametroR_sArgs.Size = 4000;
                _parametroR_sArgs.Value = null;

                dbCommand.Parameters.Add(_parametroR_sArgs);
                #endregion sArgs

                #region Retorno
                DbParameter _parametroRettype = dbCommand.CreateParameter();

                _parametroRettype.ParameterName = "R_Retorno";
                _parametroRettype.Direction = ParameterDirection.Output;
                _parametroRettype.DbType = DbType.Int32;
                _parametroRettype.Value = 0;

                dbCommand.Parameters.Add(_parametroRettype);
                #endregion Retorno
                #endregion Parâmetros de Saída

                #region Execute
                dbCommand.CommandText = _sql.ToString();
                this.DataBase.ExecuteNonQuery(dbCommand);

                _response.Sucesso = Convert.ToBoolean(this.DataBase.GetParameterValue(dbCommand, "R_Retorno")) ? true : false;

                if (!_response.Sucesso)
                {
                    _response.CodigoErro = Convert.ToInt32(_parametroR_nErro.Value);
                    _response.Argumentos = Convert.ToString(_parametroR_sArgs.Value);
                }
                #endregion Execute
            }
            return _response;
        }
        #endregion ExecutarCasamentoRecasamento       

        private string FormatarData(DateTime data, string separador)
        {
            return data.Day.ToString().PadLeft(2, '0') + separador +
                data.Month.ToString().PadLeft(2, '0') + separador +
                data.Year.ToString();
        }

        #endregion Métodos Privados
    }
}
